#include<Arduino.h>                             //Arduino库
#include<Ticker.h>                              //Ticker库
#include<TM1637.h>                              //tm1637库  
#define CLK 16                                  //tm1637 CLK引脚
#define DIO 17                                  //tm1637 DIO引脚
TM1637 tm1637(CLK,DIO);                         //tm1637对象
Ticker t1;                                      //定时器对象1colok_jishi()
Ticker t2;                                      //定时器对象2colok_san()
Ticker t3;                                      //定时器对象3seth_san()
Ticker t4;                                      //定时器对象4setm_san()
Ticker t5;                                      //定时器对象5colok_s()
int key[4]={25,33,32,27};                       //按键引脚
int s1=0,s2=0,m1=0,m2=0,h1=0,h2=0;              //时分秒 
int l1=0,l2=0,l3,l4;                            //数码管灯序号
int i;                                          //循环变量
int pointd=1;                                   //控制闪烁的变量
int Mode=1;                                     //模式变量
int set=0;                                      //设置时间变量
int hhhset1=0,hhhset2=0,mmmset1=0,mmmset2=0;    //设置时分秒变量（但hhhset2,mmmset2未使用）
int sss=1;                                      //控制秒的变量
int h,m;                                        //时，分

/*******************************************定义函数*******************************************************************/

void start()                                    //初始状态
{
    tm1637.point(POINT_ON);                     //数码管小数点开启
    tm1637.display(0,l1);                       //数码管1号显示
    tm1637.display(1,l2);                       //数码管2号显示
    tm1637.display(2,l3);                       //数码管3号显示
    tm1637.display(3,l4);                       //数码管4号显示
}

void colok()                                    //闹钟
{
   s1++;                                        //秒个位加1
    if(s1==10)                                  //秒个位加到10
    {
        s1=0;                                   //秒个位归0 
        s2++;                                   //秒十位加1
        if(s2==6)                               //秒十位加到6
        {
            s2=0;                               //秒十位归0
            m1++;                               //分个位加1
            if(m1==10)                          //分个位加到10                
            {
                m1=0;                           //分个位归0
                m2++;                           //分十位加1                 
               if(m2==6)                        //分十位加到6    
                {
                    m2=0;                       //分十位归0
                    h1++;                       //时个位加1  
                    if(h2!=2&&h1==10)           //h2!=2&&h1=10变位
                    {
                        h1=0;                   //h1=0
                        h2=h2+1;                //h2加1进位
                        if(h2==2&&h1==4)        //h2=2&&h1=4变位
                        {
                          h1=0;                 //h1=0
                          h2=0;                 //h2=0   
                        }
                    }
                    else if(h2==2&&h1==4)       //h2=2&&h1=4变位
                    {
                        h1=0;                   //h1=0
                        h2=0;                   //h2=0
                    }
                }
            }
        }
    }
}

void colok_jishi()                              //定时器1
{
    colok();                                    //调时钟函数
    if(pointd==1)                               //计时器1小数点亮
   {
      colok();                                  //调时钟函数
      l1=h2;                                    //l1=m1
      l2=h1;                                    //l2=m2 
      l3=m2;                                    //l3=h1   
      l4=m1;                                    //l4=h2
      tm1637.point(1);                          //小数点亮
      tm1637.display(0,l1);                     //显示l1
      tm1637.display(1,l2);                     //显示l2
      tm1637.display(2,l3);                     //显示l3
      tm1637.display(3,l4);                     //显示l4
      pointd=0;                                 //pointd=0
   }
   else                                         //计时器1小数点灭
   {
      tm1637.clearDisplay();                    //清屏
      tm1637.point(0);                          //小数点灭
      tm1637.display(0,l1);                     //显示l1
      tm1637.display(1,l2);                     //显示l2
      tm1637.display(2,l3);                     //显示l3
      tm1637.display(3,l4);                     //显示l4
      pointd=1;                                 //pointd=1
   }
}

void colok_shan()                               //计时器2闪烁
{
    if(pointd==0)                               //小数点闪烁
   {
      tm1637.point(0);                          //小数点关闭      
      tm1637.clearDisplay();                    //清屏
      pointd=1;                                 //p=1
   }
   else                                         //小数点闪烁
   {
      tm1637.point(1);                          //小数点开启
      tm1637.display(3,l4);                     //tm1637显示l1
      tm1637.display(2,l3);                     //tm1637显示l2   
      tm1637.display(1,l2);                     //tm1637显示l3
      tm1637.display(0,l1);                     //tm1637显示l4
      pointd=0;                                 //p=0
   }
}

void seth_shan()                                //小时闪烁
{
   if(pointd==0)                                //小数点闪烁
   {
      tm1637.point(1);                          //小数点关闭      
      tm1637.clearDisplay();                    //清屏
      tm1637.display(3,l4);                     //tm1637显示l1
      tm1637.display(2,l3);                     //tm1637显示l2  
      pointd=1;                                 //p=1
   }
   else                                         //小数点闪烁
   {
      tm1637.clearDisplay();                    //清屏
      tm1637.point(1);                          //小数点开启
      tm1637.display(3,l4);                     //tm1637显示l1
      tm1637.display(2,l3);                     //tm1637显示l2   
      tm1637.display(1,l2);                     //tm1637显示l3
      tm1637.display(0,l1);                     //tm1637显示l4
      pointd=0;                                 //p=0
   }
}

void setm_shan()                                //分钟闪烁
{
   if(pointd==0)                                //小数点闪烁
   {
      tm1637.point(0);                          //小数点关闭      
      tm1637.clearDisplay();                    //清屏
      tm1637.display(0,l1);                     //tm1637显示l1
      tm1637.display(1,l2);                     //tm1637显示l2
      pointd=1;                                 //p=1
    }
    else
    {
      tm1637.clearDisplay();                    //清屏
      tm1637.point(1);                          //小数点开启
      tm1637.clearDisplay();                    //清屏
      tm1637.display(0,l1);                     //tm1637显示l1
      tm1637.display(1,l2);                     //tm1637显示l2
      tm1637.display(2,l3);                     //tm1637显示l3
      tm1637.display(3,l4);                     //tm1637显示l4
      pointd=0;                                 //p=0
    }
}

void colok_s()                                  //秒
{
  if(pointd==1)                                 //小数点闪烁
   {
      colok();                                  //调用时种函数
      l4=s1;                                    //l4=s1
      l3=s2;                                    //l3=s2   
      l2=0;                                     //l2=0
      l1=0;                                     //l1=0
      tm1637.clearDisplay();                    //清屏
      tm1637.point(1);                          //小数点亮
      tm1637.display(3,l4);                     //显示l4 
      tm1637.display(2,l3);                     //显示l3
      tm1637.display(1,l2);                     //显示l2 
      tm1637.display(0,l1);                     //显示l1
      pointd=0;                                 //p=0
   }
   else                                         //计时器2小数点灭
   {
      tm1637.clearDisplay();
      tm1637.point(0);                          //小数点灭
      tm1637.display(3,l4);                     //显示l4
      tm1637.display(2,l3);                     //显示l3
      tm1637.display(1,l2);                     //显示l2 
      tm1637.display(0,l1);                     //显示l1
      pointd=1;
   }
}

void hsetjia()                                  //调时加
{
  h1++;                                         //h1加1
  if(h1==10)                                    //h1=10              
  {
    h1=0;                                       //h1=0
    h2++;                                       //h2加1
    if(h2==2&&h1==4)                            //h2=2,h1=4
    {
      h2=0;                                     //h2=0
      h1=0;                                     //h1=0
    }
  }
  l1=h2;                                        //l1=h2
  l2=h1;                                        //l2=h1
}

void hsetj()                                    //调时减
{
  h=h1+h2*10;                                   //h=h1+h2*10
  if (h==0)                                     //h=0
  h=23;                                         //h=23
  else                                          //h不等于0
  h--;                                          //h减1
  h1=h%10;                                      //h1=h%10
  h2=h/10;                                      //h2=h/10
  l1=h2;                                        //l1=h2
  l2=h1;                                        //l2=h1
}

void msetjia()                                  //调分加
{
  m1++;                                         //m1加1
  if(m1==10)                                    //m1=10
  {
    m1=0;                                       //m1=0
    m2++;                                       //m2加1
    if(m2==6)                                   //m2=6
    {
      m2=0;                                     //m2=0
      m1=0;                                     //m1=0
    }
  }
  l3=m2;                                        //l3=m2
  l4=m1;                                        //l4=m1
}

void msetjian()                                 //调分减
{
  m=m1+m2*10;                                   //m=m1+m2*10
  if (m==0)                                     //m=0
  m=59;                                         //m=59
  else                                          //m!=0
  m--;                                          //m减1
  m1=m%10;                                      //m1=m%10
  m2=m/10;                                      //m2=m/10
  l3=m2;                                        //l3=m2
  l4=m1;                                        //l4=m1
}

/**************************************************主函数**************************************************************/

void setup()                                    //sutup函数
{
  for(i=0;i<4;i++)                              //设置按键为输入
  pinMode(key[i],INPUT_PULLUP);                 //设置按键为输入
  tm1637.init();                                //初始化数码管
  tm1637.set(BRIGHT_TYPICAL);                   //设置数码管亮度
  tm1637.point(POINT_ON);                       //设置数码管小数点
  start();                                      //启动start函数
  t1.attach(0.5,colok_jishi);                   //计时器1每0.5秒调用一次colok_jishi函数
}

void loop()                                     //loop函数
{
  if (Mode==1)                                  //Mode=1
   {
        if(digitalRead(key[0])==LOW)            //按键1
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[0])==0);      //等待按键释放
            t1.detach();                        //计时器1停止
            t3.detach();                        //计时器3停止
            t4.detach();                        //计时器4停止
            t5.detach();                        //计时器5停止
            t2.attach(0.5,colok_shan);          //计时器2每0.5秒调用一次colok_shan函数
            Mode=0;                             //Mode=0
            set=1;                              //set=1
            sss=0;                              //sss=0
            hhhset1=0;                          //hhhset1=0
            hhhset2=0;                          //hhhset2=0（现在不用了）
            mmmset1=0;                          //mmmset1=0
            mmmset2=0;                          //mmmset2=0（现在不用了）     
        } 
    }
    else                                        //Mode!=1
    {
        if(digitalRead(key[0])==LOW)            //按键1
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[0])==LOW);    //等待按键释放
            t2.detach();                        //计时器2停止
            t3.detach();                        //计时器3停止
            t4.detach();                        //计时器4停止
            t5.detach();                        //计时器5停止
            t1.attach(0.5,colok_jishi);         //计时器1每0.5秒调用一次colok_jishi函数
            Mode=1;                             //Mode=1
            set=0;                              //set=0
            sss=1;                              //sss=1
            hhhset1=0;                          //hhhset1=0
            hhhset2=0;                          //hhhset2=0（现在不用了）
            mmmset1=0;                          //mmmset1=0
            mmmset2=0;                          //mmmset2=0（现在不用了）
        }
    }
    if(set==1)                                  //set=1
    {
        if(digitalRead(key[1])==LOW)            //按键2
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[1])==0);      //等待按键释放
            t1.detach();                        //计时器1停止
            t2.detach();                        //计时器2停止
            t4.detach();                        //计时器4停止
            t5.detach();                        //计时器5停止
            t3.attach(0.5,seth_shan);           //计时器3每0.5秒调用一次seth_shan函数
            set=2;                              //set=2
            hhhset1=1;                          //hhhset1=1
            hhhset2=1;                          //hhhset2=1（现在不用了）
            mmmset1=0;                          //mmmset1=0
            mmmset2=0;                          //mmmset2=0（现在不用了）
        }
    }
    if(set==2)                                  //set=2
    {
        if(digitalRead(key[1])==LOW)            //按键2
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[1])==0);      //等待按键释放
            t1.detach();                        //计时器1停止
            t2.detach();                        //计时器2停止
            t3.detach();                        //计时器3停止
            t5.detach();                        //计时器5停止
            t4.attach(0.5,setm_shan);           //计时器4每0.5秒调用一次setm_shan函数
            set=1;                              //set=1
            hhhset1=0;                          //hhhset1=0
            hhhset2=0;                          //hhhset2=0（现在不用了）
            mmmset1=1;                          //mmmset1=1
            mmmset2=1;                          //mmmset2=1（现在不用了）
        }
    }
    if(hhhset1==1)                              //hhhset1=1
    {
        hhhset1=2;                              //hhhset1=2
        if(digitalRead(key[2])==LOW)            //按键3
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[2])==LOW);    //等待按键释放
            hsetjia();                          //调用hsetjia函数
        }
    }
    if(hhhset1==2)                              //hhhset1=2
    {
      hhhset1=1;                                //hhhset1=1
      if(digitalRead(key[3])==LOW)              //按键4
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[3])==LOW);    //等待按键释放
            hsetj();                            //调用hsetj函数
        }   
    }
    if(mmmset1==1)                              //mmmset1=1
    {
        mmmset1=2;                              //mmset1=2
        if(digitalRead(key[2])==LOW)            //按键3
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[2])==LOW);    //等待按键释放
            msetjia();                          //调用msetjia函数
        }
    }
    if(mmmset1==2)                              //mmmset1=2
    {
        mmmset1=1;                              //mmset1=1
        if(digitalRead(key[3])==LOW)            //按键4
        {
            delay(10);                          //延时10ms
            while(digitalRead(key[3])==LOW);    //等待按键释放
            m=m1+m2*10;                         //m=m1+m2*10
            if (m==0)                           //如果m=0
            m=59;                               //m=59
            else                                //否则
            m--;                                //m--
            m1=m%10;                            //m1=m%10
            m2=m/10;                            //m2=m/10
            l3=m2;                              //l3=m2
            l4=m1;                              //l4=m1
        }   
    }
    if(sss==1)                                  //sss=1
    {
        if(digitalRead(key[2])==LOW&&digitalRead(key[3])==LOW)             //按键3
        {
            delay(10);                                                     //延时10ms
            while(digitalRead(key[2])==LOW&&digitalRead(key[3])==LOW);     //等待按键释放
            t1.detach();                         //停止t1
            t2.detach();                         //停止t2
            t3.detach();                         //停止t3
            t4.detach();                         //停止t4
            t5.attach(0.5,colok_s);              //启动t5
            sss=2;                               //sss=2
        }
    }
    if(sss==2)                                   //sss=2
    {
        if(digitalRead(key[2])==LOW&&digitalRead(key[3])==LOW)             //按键3
        {
            delay(10);                                                     //延时10ms
            while(digitalRead(key[2])==LOW&&digitalRead(key[3])==LOW);     //等待按键释放
            t2.detach();                         //停止t2
            t3.detach();                         //停止t3
            t4.detach();                         //停止t4
            t5.detach();                         //停止t5
            t1.attach(0.5,colok_jishi);          //启动t1
            sss=0;                               //sss=0
        }
    }
}   